#include "protocal.h"
#include "hardware.h"
#include "app_functions.h"
#include "timer.h"

/******************/
//通讯全局变量定义
uint8_t 		 	gu8_IsQueryversion;			//是否查询版本号
uint8_t 			gu8_Isdebug;				//是否进入调试状态，通讯指令控制

uint8_t 		 	gu8_EmerFlag;				//电源状态
uint8_t  		 	gu8_com_data_deal_end;		//接收数据处理完毕
uint8_t 			gu8_com_data_init_end;		//开机等待数据初始化完成再上传
uint8_t			 	gu8_com_type_version;
uint8_t				gu8_uarthostRxStatusFlag;
uint8_t				gu8_uarthostRxdone;

#if CHECK_BAT_LIION_EN > 0
uint8_t				gu8_uartslaveRxStatusFlag;
uint8_t				gu8_bat_command_flag;		//用于记录(主机)发送给电池包的命令，方便对收到的应答进行判断
uint8_t				gu8_bat_respond_flag;		//用于记录电池包是否响应相应命令，读取电池包数据之前需要确认
#endif
volatile uint8_t 	gu8_uart_host_rx_remain;
volatile uint8_t 	gu8_uart_host_tx_remain;
#if 0
volatile uint8_t 	gu8_uart_host_rx_rev_len;	
volatile uint8_t 	gu8_uart_host_rx_index;
volatile uint8_t 	gu8_uart_host_rx_trace;	
volatile uint8_t    gu8_uart_host_rx_tail;
#endif
volatile uint8_t 	gu8_uart_host_tx_index;
volatile uint8_t 	gu8_uart_host_tx_trace;


#if CHECK_BAT_LIION_EN > 0
volatile uint8_t 	gu8_uart_slave_rx_remain;
volatile uint8_t 	gu8_uart_slave_tx_remain;
volatile uint8_t 	gu8_uart_slave_rx_index;
volatile uint8_t 	gu8_uart_slave_tx_index;
volatile uint8_t    gu8_uart_slave_rx_tail;
#endif

uint8_t          	gu8_uart_host_rx_buf[USART_BUFFER_SIZE] = {0};
uint8_t          	gu8_uart_host_tx_buf[USART_BUFFER_SIZE] = {0};
uint8_t 		 	gu8_uart_host_send[PROTOCAL_BUF_SIZE] = {0};
#if 0
uint8_t			 	gu8_uart_host_recv[PROTOCAL_BUF_SIZE] = {0};
#endif

#if CHECK_BAT_LIION_EN > 0
uint8_t          	gu8_uart_slave_rx_buf[USART_BUFFER_SIZE] = {0};
uint8_t          	gu8_uart_slave_tx_buf[USART_BUFFER_SIZE] = {0};
uint8_t 		 	gu8_uart_slave_send[USART_BUFFER_SIZE] = {0};
uint8_t			 	gu8_uart_slave_recv[PROTOCAL_BUF_SIZE] = {0};
#endif

uint8_t	gu8_escape_send_data[PROTOCAL_BUF_SIZE] = {0};
uint8_t	gu8_escape_over_send_data[PROTOCAL_BUF_SIZE] = {0};

//备份缓存区
uint8_t gu8_escape_over_send_data_bk_len;
uint8_t	gu8_escape_over_send_data_bk[PROTOCAL_BUF_SIZE] = {0};

uint8_t gu8_revhostACK = YES;

Uart_Msg_Rec  		gst_uart_msg_rec[uart_msg_rec_buffer_num];
Bus_Pack_t  		gst_bus_pack;


#ifdef debug_f									//该宏定义在头文件
//用于调试时的输出变量
uint16_t u6_debug_value = 0;
#endif

/******************/



void Protocal_Init(void)
{
	gu8_uart_host_rx_remain = 0;
	gu8_uart_host_tx_remain = 0;
	gu8_uart_host_tx_index = 0;
#if 0
	gu8_uart_host_rx_index = 0;
	gu8_uart_host_rx_trace = 0;
	gu8_uart_host_rx_tail = 0;
#endif
#if CHECK_BAT_LIION_EN > 0	
	gu8_uart_slave_rx_remain = 0;
	gu8_uart_slave_tx_remain = 0;
	gu8_uart_slave_rx_index = 0;
	gu8_uart_slave_tx_index = 0;
	gu8_uart_slave_rx_tail = 0;
#endif	

	gu8_uarthostRxStatusFlag = 0;

#if CHECK_BAT_LIION_EN > 0
	gu8_uartslaveRxStatusFlag = 0;
#endif

	gu8_EmerFlag = 0;
	gu8_com_data_deal_end = NO;
	gu8_com_data_init_end = NO;
	gu8_com_type_version = 0x01;
	
#if CHECK_BAT_LIION_EN > 0	
	gu8_bat_command_flag = PROTOCAL_BAT_INFO_FLAG;
	gu8_bat_respond_flag = 0;
#endif

	gst_bus_pack.ctrl.NR = 0;
	gst_bus_pack.ctrl.NS = 0;
	gst_bus_pack.ctrl.PF = 1;
	gst_bus_pack.ctrl.DI = 1;
	gu8_escape_over_send_data_bk_len = 0;
	gu8_revhostACK = 0xFF;

	gu8_IsQueryversion = NO;
	gu8_Isdebug = NO;
}

uint16_t CRC_16(uint8_t *pdata, uint16_t len)
{
	uint16_t crc16 = 0xffff;
	uint16_t i,j;

	if (pdata == NULL)
	{
		return 0;
	}
	
	for (i=0;i<len;i++)
	{
		crc16 ^= (uint16_t)(*pdata)<<8;
		for (j=0;j<8;j++)
		{
			if (crc16&0x8000)
			{
				crc16 <<= 1;
				crc16 ^= 0x1021;
			}
			else
			{
				crc16 <<= 1;
			}
		}
		pdata++;
	}
	return crc16;
}

uint16_t protocal_make_send_data(const Bus_Pack_t pack, uint8_t *pro_send_data, uint8_t buff_size)
{
    uint8_t *pcur = pro_send_data;
	uint16_t crc16 = 0;
	
	*pcur++ = PROTOCAL_START_FLAG;				//帧头
    *pcur++ = pack.addr;						//地址
    *pcur++ = *(uint8_t*)&(pack.ctrl);			//控制字段
	*pcur++ = pack.info.cmd;					//信息字段
	*pcur++ = pack.info.len;					//
	if (pack.info.len > 0 && pack.info.len <= (buff_size-5-2))
	{
		memcpy(pcur, pack.info.data, pack.info.len);
		pcur += pack.info.len;	
	}			

	//计算校验码，不包括帧头
	crc16 = CRC_16(&pro_send_data[1], (uint16_t)(pcur-pro_send_data-1));		
	*pcur++ = crc16 & 0xff;	
	*pcur++ = crc16>>8;	
	*pcur++ = PROTOCAL_END_FLAG;				//帧尾
	
    return (uint16_t)(pcur - pro_send_data);
}

uint16_t Protocal_Escape_Send_Data(const uint8_t *Original_Data, const uint16_t Len_Original_Data, uint8_t *Escape_Data)
{
    const uint8_t *pcur = Original_Data;			
	uint16_t  i = 1, j = 1;

	*Escape_Data = PROTOCAL_START_FLAG;
	
	for (i=1; i<(Len_Original_Data-1); i++)			//帧头帧尾不转义
	{
		if (*(pcur+i) == PROTOCAL_START_FLAG)		//0x7E
		{
			*(Escape_Data+(j++%PROTOCAL_BUF_SIZE)) = PROTOCAL_ESCAPE_FLAG;
			*(Escape_Data+(j++%PROTOCAL_BUF_SIZE)) = 0x5E;
		}
		else if(*(pcur+i) == PROTOCAL_ESCAPE_FLAG)	//0x7D
		{
			*(Escape_Data+(j++%PROTOCAL_BUF_SIZE)) = PROTOCAL_ESCAPE_FLAG;
			*(Escape_Data+(j++%PROTOCAL_BUF_SIZE)) = 0x5D;
		}
		else
		{
			*(Escape_Data+(j++%PROTOCAL_BUF_SIZE)) = *(pcur+i);
		}
	}
	
	*(Escape_Data+(j++%PROTOCAL_BUF_SIZE)) = PROTOCAL_END_FLAG;
	
	return j;										//返回转义后的总长度
}

/*unsigned char CRC8_Calculate(unsigned char* ptr, unsigned char len)
{
	unsigned char i,crc = 0;
	while(len--)
	{
		crc ^= *ptr++;
		for(i=0; i<8; i++)
		{
			if (crc & 0x80)
				crc = (crc<<1)^0x31;
			else
				crc<<=1;
		}	
	}
	return crc;
}

static unsigned char crc_table[256] = {0};
unsigned char CRC8_Calculate_With_Table(unsigned char* ptr, unsigned char len)
{
	unsigned char crc = 0;
	while(len--)
	{
		crc = crc_table[crc ^ (*ptr++)];
	}
	return crc;
}

void Create_CRC_Tab(unsigned char* ptr, unsigned int len)
{
	unsigned int i;
	unsigned char j;
	if (ptr != 0 && len == 256)
	{
		for(i=0; i<=0xFF; i++)
		{
			*(ptr+i) = CRC8_Calculate((unsigned char*)&i,1);
		}
	}
	
}

void
Protocal_Escape_Send_Data(unsigned char* Original_Data, unsigned int Len_Original_Data, unsigned char* Escape_Data)
{
    unsigned char *pcur = Original_Data;
	unsigned int i = 0, j = 0;
	for (i=0; i<Len_Original_Data; i++)
	{
		if (*(pcur+i) == 0xEB)
		{
			*(Escape_Data+j) = 0x1B;
			*(Escape_Data+j+1) = 0xFF;
			j = j+2;
		}
		else if(*(pcur+i) == 0x1B)
		{
			*(Escape_Data+j) = 0x1B;
			*(Escape_Data+j+1) = 0x00;
			j = j+2;
		}
		else
		{
			*(Escape_Data+j) = *(pcur+i);
			j++;
		}
	}
}

void
Protocal_Escape_REV_Data(unsigned char* Original_Data, unsigned int Len_Original_Data, unsigned char* Escape_Data) //鏁版嵁鍘绘帀甯уご鍚庢墽琛?
{
    unsigned char *pcur = Original_Data;
	unsigned int i = 0, j = 0;
	for (i=0; i<Len_Original_Data; i++)
	{
		if (*(pcur+i) == 0x1B)
		{
			if (*(pcur+i+1) == 0x00)
				*(Escape_Data+j) = 0x1B;
			else if (*(pcur+i+1) == 0xFF)
				*(Escape_Data+j) = 0xEB;
			i++;
			j++;
		}
		else
		{
			*(Escape_Data+j) = *(pcur+i);
			j++;
		}
	}
}
*/


uint8_t ChkSum(uint8_t *dataBuf, uint8_t dataLen)
{
	uint8_t ret = 0, i;
	for (i = 0; i < dataLen;i++)
	{
		ret = ret + *(dataBuf+i);
	}
	return ret;
}

uint8_t protocal_make_cmd_data(uint8_t cmd, const uint8_t* data, uint8_t len, uint8_t * pro_send_data)
{
    uint8_t *pcur = pro_send_data;
	*pcur++ = PROTOCAL_TEST_START_FLAG;
    *pcur++ = PROTOCAL_SLAVE_ID;
    *pcur++ = (len+1) & 0xFF;	//len(data)+1(cmd)
    *pcur++ = cmd & 0xFF;		//cmd
    memcpy(pcur, data, len);
    pcur += len;
    uint8_t l = (uint8_t)(pcur - &pro_send_data[3]);
	*pcur++ = ChkSum(&pro_send_data[3], l);		//校验码
    l = (uint8_t)(pcur - &pro_send_data[0]);
    return l;
}

/**
 * @brief Sys_state_UpLoad
 * 检查更新系统有变动的状态和信息，把有变化的信息装填到数组
 * @param info_new 系统最新的状态信息
 		  info_save 系统上一次的状态信息
 		  pdata 数组首地址
 		  info_len 可更新的信息长度
 * @return uint8_t 装填长度
 */
uint8_t Sys_state_UpLoad(uint32_t info_new, uint32_t info_save, uint8_t* pdata, uint8_t info_len)
{
	uint8_t i, j;
	uint32_t temp;
	
	i = 0;
	if ((info_new & 0xF) != (info_save & 0xF))					//主电状态有变化
	{
		if ((info_new & 0xF) == 0)
		{
			if ((info_len-i) < 3)
			{
				return i;
			}
			pdata[i++] = 0;						//板地址
			pdata[i++] = 0x01;					//偏移
			pdata[i++] = 0x01;					//正常
		}
		else
		{
			temp = (~info_save) & info_new;
			for(j=1;j<4;j++)
			{
				if ((temp & (1<<j)) != 0)
				{
					if ((info_len-i) < 3)
					{
						return i;
					}
					pdata[i++] = 0;
					pdata[i++] = 0x01;
					if (j == 1)
					{
						pdata[i++] = 0x07;
					}
					else
					{
						pdata[i++] = j+1;
					}
				}
			}
		}
	}
		
	if ((info_new & 0x7FF0) != (info_save & 0x7FF0))		//备电状态有变化
	{
		if ((info_new & 0x1360) == 0)			//bit5(充电)、6(欠压)、8(开路)、9(短路)、12(内阻异常)没有置1认为正常
		{	
			if ((info_len-i) < 3)
			{
				return i;
			}
			pdata[i++] = 0;						//板地址
			pdata[i++] = 0x02;					//偏移
			pdata[i++] = 0x01;					//正常
		}
		
		{
			temp = (~info_save) & info_new;
			for(j=5;j<15;j++)
			{
				if ((info_new & (1<<j)) != 0)
				{
					if ((info_len-i) < 3)
					{
						return i;
					}
					pdata[i++] = 0;
					pdata[i++] = 0x02;
					pdata[i++] = j-3;
				}
			}
		}
	}

	if ((info_new & 0x100000) != 0)		//备电电压有变化
	{
		if ((info_len-i) < 3)
		{
			return i;
		}
		pdata[i++] = 0;
		pdata[i++] = 0x03;
		pdata[i++] = (uint8_t)(gst_battery.voltage/20);
	}

	if ((info_new & 0x200000) != 0)		//备电电量有变化
	{
		if ((info_len-i) < 3)
		{
			return i;
		}
		pdata[i++] = 0;
		pdata[i++] = 0x04;
		pdata[i++] = (uint8_t)(gst_battery.capacity);
	}

	if ((info_new & 0x400000) != 0)		//备电电池1电压有变化
	{
		if ((info_len-i) < 3)
		{
			return i;
		}
		pdata[i++] = 0;
		pdata[i++] = 0x05;
		pdata[i++] = (uint8_t)(gst_battery.m1_voltage/20);
	}

	if ((info_new & 0x800000) != 0)		//备电电池2电压有变化
	{
		if ((info_len-i) < 3)
		{
			return i;
		}
		pdata[i++] = 0;
		pdata[i++] = 0x06;
		if (gst_battery.voltage >= gst_battery.m1_voltage)
		{
			pdata[i++] = (uint8_t)((gst_battery.voltage-gst_battery.m1_voltage)/20);
		}
		else
		{
			pdata[i++] = 0;
		}
	}

	if ((info_new & 0xF0000000) != (info_save & 0xF0000000))		//故障状态有变化
	{
		for(j=28;j<32;j++)
		{
			if (((info_new>>j) & 0x01) != ((info_save>>j) & 0x01))
			{
				
				if (((info_new>>j) & 0x01) != 0)
				{
					if ((info_len-i) < 3)
					{
						return i;
					}
					pdata[i++] = 0;
					pdata[i++] = 0xFF;
					if (j >= 30)
					{
						pdata[i++] = (j%4)+2;
					}
					else
					{
						pdata[i++] = (j%4)+1;
					}
				}
				else
				{
					if ((info_len-i) < 3)
					{
						return i;
					}
					pdata[i++] = 0;
					pdata[i++] = 0xFF;
					if (j >= 30)
					{
						pdata[i++] = ((j%4)+2)|0x80;
					}
					else
					{
						pdata[i++] = ((j%4)+1)|0x80;
					}
				}
			}
		}
		
	}

	return i;
		
}

uint32_t Handle_Cmd_And_Ack(uint32_t sys_state, uint32_t su32_sys_state_save, uint8_t* p_repeat_count)
{
	uint16_t data_len = 0;
	
	if (gu8_com_data_init_end == 0xff)			//刚上电等待数据更新完毕后再上传
	{
		if (gu8_revhostACK == YES || gu8_revhostACK == 0xFF)		//上一次状态传输成功
		{
			if (su32_sys_state_save != sys_state)	//系统状态有变化，上传状态/故障
			{
				gu8_revhostACK = NO;
				gst_bus_pack.addr = PROTOCAL_SLAVE_ADDR;
				gst_bus_pack.ctrl.PF = 1;
				gst_bus_pack.ctrl.DI = 1;
				gst_bus_pack.info.cmd = PROTOCAL_UPLOAD;
				
				data_len = Sys_state_UpLoad(sys_state, su32_sys_state_save, 
											gst_bus_pack.info.data, sizeof(gst_bus_pack.info.data));
				gst_bus_pack.info.len = data_len;
				
				su32_sys_state_save = sys_state & (~0x00F00000);

				data_len = protocal_make_send_data(gst_bus_pack,
													gu8_escape_send_data, 
													sizeof(gu8_escape_send_data));
			
				data_len = Protocal_Escape_Send_Data(gu8_escape_send_data, 
													data_len, 
													gu8_escape_over_send_data);
				//备份info字段
				gu8_escape_over_send_data_bk_len = gst_bus_pack.info.len+2;
				memcpy(gu8_escape_over_send_data_bk, &(gst_bus_pack.info), gu8_escape_over_send_data_bk_len);
				*p_repeat_count = 2;
			}
			else								//无上传信息则空应答
			{
				gst_bus_pack.addr = PROTOCAL_SLAVE_ADDR;
				gst_bus_pack.ctrl.PF = 1;
				gst_bus_pack.ctrl.DI = 1;
				gst_bus_pack.info.cmd = PROTOCAL_GETREQUEST;
				gst_bus_pack.info.len = 0;
				data_len = protocal_make_send_data(gst_bus_pack,
													gu8_escape_send_data, 
													sizeof(gu8_escape_send_data));
			
				data_len = Protocal_Escape_Send_Data(gu8_escape_send_data, 
													data_len, 
													gu8_escape_over_send_data);
			}
		}
		else if (gu8_revhostACK == NO)			//上一次状态传输失败，需要重发
		{
			if ((*p_repeat_count) > 0)
			{
				(*p_repeat_count)--;
				gst_bus_pack.addr = PROTOCAL_SLAVE_ADDR;
				gst_bus_pack.ctrl.PF = 1;
				gst_bus_pack.ctrl.DI = 1;
				memcpy(&(gst_bus_pack.info), gu8_escape_over_send_data_bk, gu8_escape_over_send_data_bk_len);
				data_len = protocal_make_send_data(gst_bus_pack,
													gu8_escape_send_data, 
													sizeof(gu8_escape_send_data));
			
				data_len = Protocal_Escape_Send_Data(gu8_escape_send_data, 
													data_len, 
													gu8_escape_over_send_data);
			}
			else
			{
				gst_bus_pack.addr = PROTOCAL_SLAVE_ADDR;
				gst_bus_pack.ctrl.PF = 1;
				gst_bus_pack.ctrl.DI = 1;
				gst_bus_pack.info.cmd = PROTOCAL_GETREQUEST;
				gst_bus_pack.info.len = 0;
				data_len = protocal_make_send_data(gst_bus_pack,
													gu8_escape_send_data, 
													sizeof(gu8_escape_send_data));
			
				data_len = Protocal_Escape_Send_Data(gu8_escape_send_data, 
													data_len, 
													gu8_escape_over_send_data);
			}
		}
	}
	else										//数据没有准备好，直接应答握手
	{
		gst_bus_pack.addr = PROTOCAL_SLAVE_ADDR;
		gst_bus_pack.ctrl.PF = 1;
		gst_bus_pack.ctrl.DI = 1;
		gst_bus_pack.info.cmd = PROTOCAL_GETREQUEST;
		gst_bus_pack.info.len = 0;
		data_len = protocal_make_send_data(gst_bus_pack,
											gu8_escape_send_data, 
											sizeof(gu8_escape_send_data));
	
		data_len = Protocal_Escape_Send_Data(gu8_escape_send_data, 
											data_len, 
											gu8_escape_over_send_data);
	}
	
	if (gu8_Isdebug == NO)
	{
		Uart_Host_Write(gu8_escape_over_send_data, (uint8_t)data_len); 
	}
	return su32_sys_state_save;
}

/**
 * @brief pro_deal_recv_data
 * 对收到的数据验证CRC，并应答通信方；
 * @param data 待处理数据
 * @return void
 */
void pro_deal_recv_data(uint8_t *p_data, uint8_t len)
{
	uint8_t *p = NULL;
	uint8_t i, j;
	static uint8_t repeat_count = 0;
	uint16_t data_len = 0;
	Bus_Ctrl_t ctrl;
	static uint32_t su32_sys_state_save = 0x11;
	uint32_t sys_state = 0;

	if (CRC_16(p_data, (len-2)) == ((p_data[len-1]<<8) + p_data[len-2]))		//校验通过
	{
		p = p_data;
		ctrl = *(Bus_Ctrl_t*)(p+1);

		if (*p == 0xFF)
		{
			su32_sys_state_save = 0x11;						//广播信息，准备重新上传信息
			return;
		}
		
		if (ctrl.NR == (gst_bus_pack.ctrl.NS+1)%8)			//上一帧成功接收
		{
			gu8_revhostACK = YES;
			repeat_count = 0;
			gst_bus_pack.ctrl.NS++;
		}
		else
		{
			if (gu8_revhostACK == YES)
			{
				gu8_revhostACK = NO;
			}
		}
		gst_bus_pack.ctrl.NR = 	ctrl.NS+1;					//确认收到主机信息
		
		sys_state = Check_Sys_State();						//获取一次系统状态
		
		switch (*(p+2)) 									//命令标识
		{
			case PROTOCAL_GETREQUEST:						//查询请求/空应答
				if (gu8_Isdebug == NO)
				{
					su32_sys_state_save = Handle_Cmd_And_Ack(sys_state, su32_sys_state_save, &repeat_count);
				}
				
			break;
			
			case PROTOCAL_UPLOAD:							//数据下发/信息上报	
				//响应、执行，暂无

				//上报
				if (gu8_Isdebug == NO)
				{
					su32_sys_state_save = Handle_Cmd_And_Ack(sys_state, su32_sys_state_save, &repeat_count);
				}
			break;

			case PROTOCAL_GETDEVICE:					//拓扑查询/拓扑应答									
				
				if (gu8_Isdebug == NO)
				{
					gst_bus_pack.addr = PROTOCAL_SLAVE_ADDR;
					gst_bus_pack.ctrl.PF = 1;
					gst_bus_pack.ctrl.DI = 1;
					gst_bus_pack.info.cmd = PROTOCAL_GETDEVICE;
					gst_bus_pack.info.len = 2;
					gst_bus_pack.info.data[0] = 0;		//板本身地址
					gst_bus_pack.info.data[1] = 0x09;	//电源类型
					
					data_len = protocal_make_send_data(gst_bus_pack,
											  		 	gu8_escape_send_data, 
											  		 	sizeof(gu8_escape_send_data));
				
					data_len = Protocal_Escape_Send_Data(gu8_escape_send_data, 
														data_len, 
														gu8_escape_over_send_data);
					Uart_Host_Write(gu8_escape_over_send_data, (uint8_t)data_len); 
				}
			break;

			case PROTOCAL_GETVERION:					//查询软件版本号
				
				if (gu8_Isdebug == NO)
				{
					gst_bus_pack.addr = PROTOCAL_SLAVE_ADDR;
					gst_bus_pack.ctrl.PF = 1;
					gst_bus_pack.ctrl.DI = 1;
					gst_bus_pack.info.cmd = PROTOCAL_GETVERION;

					j = 0;
					gst_bus_pack.info.data[j++] = 0;		//板本身地址
					
					gst_bus_pack.info.data[j++] = 0;		//协议版本
					gst_bus_pack.info.data[j++] = 0;		//协议版本
					gst_bus_pack.info.data[j++] = 1;		//协议版本

					gst_bus_pack.info.data[j++] = 1;		//软件版本，V1.0beta3
					gst_bus_pack.info.data[j++] = 0;		//软件版本
					gst_bus_pack.info.data[j++] = 6;		//软件版本

					gst_bus_pack.info.data[j++] = 0;		//硬件版本，V0.3
					gst_bus_pack.info.data[j++] = 0;		//硬件版本
					gst_bus_pack.info.data[j++] = 3;		//硬件版本

					gst_bus_pack.info.data[j++] = 0;		//设备子类型

					for(i=0;i<32;i++)						//设备ID
					{
						gst_bus_pack.info.data[j++] = i%9;
					}
					gst_bus_pack.info.len = j;
					
					data_len = protocal_make_send_data(gst_bus_pack,
											  		 	gu8_escape_send_data, 
											  		 	sizeof(gu8_escape_send_data));
				
					data_len = Protocal_Escape_Send_Data(gu8_escape_send_data, 
														data_len, 
														gu8_escape_over_send_data);
					Uart_Host_Write(gu8_escape_over_send_data, (uint8_t)data_len); 
				}
			break;
			
			case PROTOCAL_CMD_QUERY_VERSION:				//产测查询软件版本号
				gu8_IsQueryversion = YES;
				Uart_Host_Write((const uint8_t*)_SOFEWARE_VERSION, sizeof(_SOFEWARE_VERSION));
			break;
			
			case PROTOCAL_CMD_DEBUG:						//调试输出模式，当产测开关
				if (*(p+3) == PROTOCAL_CMD_SEQUENCE_1 
					&& *(p+4) == PROTOCAL_CMD_SEQUENCE_2)	//命令序列OK
				{
					if (gu8_Isdebug == NO)
					{
						gu8_Isdebug = YES;
					}
					else
					{
						gu8_Isdebug = NO;
					}
				}
			break;
				
			case PROTOCAL_CMD_POWEROFF: 					//关机
				if (flag_read(&(gu8_output_power_flag), STATE) == BAT_OUT 
					&& (flag_read(&(gst_acpower.ACPOWER_FLAG_VOLTAGE_LOW), ACTION_MAINOFF) == SET)) 							//只有备电工作情况下响应
				{
					flag_operation(&(gu8_tiger_flag), SET, ACTION_BATOFF);					
				}
			break;
			
			case PROTOCAL_CMD_TSET: 						//工装生产电池内阻测试时间设置，单位为秒
				if (gu8_Isdebug == YES)
				{
					if ((((*(p+3)<<8) + *(p+4))/60) > 0xFF) 								//大于255分钟，按255分钟算
					{
						gu8_check_battery_resistance_time = 0xFF;								//255分钟
						gu16_check_battery_resistance_ms = 60000;								//60S
					}
					else if ((((*(p+3)<<8) + *(p+4))/60) == 0)								//小于60S
					{
						gu8_check_battery_resistance_time = 1;
						gu16_check_battery_resistance_ms = (uint16_t)(((*(p+3)<<8) + *(p+4))*1000);
					}
					else																	//1 ~ 255分钟
					{
						gu8_check_battery_resistance_time = (uint8_t)(((*(p+3)<<8) + *(p+4))/60);	//分钟
						gu16_check_battery_resistance_ms = 60000;								//60S
					}
					
					gu16_battery_res_timer = 0; 					//设置后重新计时
					CLEAR_TIMER(TIMER_CHECK_BATTERY_RESISTANCE);
				}
			break;

			case PROTOCAL_CMD_CALIB:										//校准，现在开放5V和AC电压校准
				if (*(p+3) == PROTOCAL_CMD_SEQUENCE_1 
					&& *(p+4) == PROTOCAL_CMD_SEQUENCE_2)					//命令序列OK
				{
					//5V，需要单独标定
					float f_vcc = 0;
					f_vcc = ((*(p+5)<<8) + *(p+6))/1000.0;					//5V标定值
					if (f_vcc >= 4.80 && f_vcc <= 5.20)						//标定值有效，准备标定5V
					{
						gf_vmcu = f_vcc;
						gs8_calib_ac_value = 0;								//标定5V之后先把其他标定值恢复为0
						FLASH_WRITE_BYTE(FLASH_S_ADDR+0x03, *(p+5));
						FLASH_WRITE_BYTE(FLASH_S_ADDR+0x04, *(p+6));
						FLASH_WRITE_BYTE(FLASH_S_ADDR+0x02, gs8_calib_ac_value);
						if (FLASH_READ_BYTE(FLASH_S_ADDR+0x03) != *(p+5) 
							|| FLASH_READ_BYTE(FLASH_S_ADDR+0x04) != *(p+6)
							|| FLASH_READ_BYTE(FLASH_S_ADDR+0x02) != gs8_calib_ac_value)
						{
							uint8_t info_strings[25] = "Write EEPROM Error!";
							Uart_Host_Write(info_strings, sizeof(info_strings));
						}
					}
					//准备标定其他参数
					else													
					{
						//AC
						int16_t s8_ac = 0;
						s8_ac = (((*(p+9)<<8) + *(p+10))/100.0) - gst_acpower.voltage;		//AC标定值
						if (s8_ac >= -15 && s8_ac <= 15)
						{
							gs8_calib_ac_value = (int8_t)s8_ac;
							FLASH_WRITE_BYTE(FLASH_S_ADDR+0x02, gs8_calib_ac_value);
							if (FLASH_READ_BYTE(FLASH_S_ADDR+0x02) != gs8_calib_ac_value)
							{
								uint8_t info_strings[25] = "Write EEPROM Error!";
								Uart_Host_Write(info_strings, sizeof(info_strings));
							}
						}
					}
				}
				break;

				default: 										//总线指令不支持
					
					if (gu8_Isdebug == NO)
					{
						gst_bus_pack.addr = PROTOCAL_SLAVE_ADDR;
						gst_bus_pack.ctrl.PF = 1;
						gst_bus_pack.ctrl.DI = 1;
						gst_bus_pack.info.cmd = PROTOCAL_NOTREQUEST;
						gst_bus_pack.info.len = 0;
						
						data_len = protocal_make_send_data(gst_bus_pack,
												  		 	gu8_escape_send_data, 
												  		 	sizeof(gu8_escape_send_data));
					
						data_len = Protocal_Escape_Send_Data(gu8_escape_send_data, 
															data_len, 
															gu8_escape_over_send_data);
						Uart_Host_Write(gu8_escape_over_send_data, (uint8_t)data_len); 
					}
			break;
		}
	}
}

void Judge_Uart_Receive_Done(void)						//判断通讯是否结束
{
	static uint8_t  u8_uart_host_com_end_time = 0;

	if ((gu8_uarthostRxStatusFlag & 0x02) != 0)			//主机通讯开始，在接收中断置位
	{
		if ((gu8_uarthostRxStatusFlag & 0x04) == 0)	
		{
			gu8_uarthostRxStatusFlag |= 0x04; 			//判断结束标志位置位
		}
		else
		{
            u8_uart_host_com_end_time++;
            if(u8_uart_host_com_end_time >= 2)      	//1~2ms
            {
                u8_uart_host_com_end_time = 0;
                gu8_uarthostRxStatusFlag |= 0x08; 		//两次间隔一致，通讯结束
				gu8_uarthostRxStatusFlag &= ~0x02;
				gu8_com_data_deal_end &= ~0x01; 		//清除数据处理标志位，表示uart_host有数据未处理
            }
		}
		
	}
}


